home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / bin / revdep-rebuild < prev    next >
Text File  |  2006-05-08  |  20KB  |  646 lines

  1. #! /bin/bash
  2.  
  3. # Copyright 1999-2005 Gentoo Foundation
  4. # $Header$
  5.  
  6. # revdep-rebuild: Reverse dependency rebuilder.
  7. # Original Author: Stanislav Brabec
  8. # Current Maintainer: Paul Varner <fuzzyray@gentoo.org>
  9.  
  10. # Known problems:
  11. #
  12. # In exact ebuild mode revdep-rebuild can fail to properly order packages,
  13. # which are not up to date.
  14. # http://bugs.gentoo.org/show_bug.cgi?id=23018
  15. #
  16. # Rebuilding using --package-names mode should be default, but emerge has no
  17. # feature to update to latest version of defined SLOT.
  18. # http://bugs.gentoo.org/show_bug.cgi?id=4698
  19.  
  20. # Customizable variables:
  21. #
  22. # LD_LIBRARY_MASK - Mask of specially evaluated libraries
  23. # SEARCH_DIRS - List of directories to search for executables and libraries
  24. # SEARCH_DIRS_MASK - List of directories to not search
  25. #
  26. # These variables can be prepended to either by setting the variable in 
  27. # your environment prior to execution, or by placing an entry in
  28. # /etc/make.conf.
  29. #
  30. # An entry of "-*" means to clear the variable from that point forward.
  31. # Example: env SEARCH_DIRS="/usr/bin -*" revdep-rebuild will set SEARCH_DIRS
  32. # to contain only /usr/bin
  33.  
  34. if [ "$1" = "-h" -o "$1" = "--help" ]
  35. then
  36.     echo "Usage: $0 [OPTIONS] [--] [EMERGE_OPTIONS]"
  37.     echo
  38.     echo "Broken reverse dependency rebuilder."
  39.     echo
  40.     echo "  -X, --package-names  Emerge based on package names, not exact versions"
  41.     echo "      --library NAME   Emerge existing packages that use the library with NAME"
  42.     echo "      --library=NAME   NAME can be a full path to the library or a basic"
  43.     echo "                       regular expression (man grep)"
  44.     echo " -nc, --no-color       Turn off colored output"
  45.     echo "  -i, --ignore         Ignore temporary files from previous runs"
  46.     echo "  -q, --quiet          Be less verbose (also passed to emerge command)"
  47.     echo " -vv, --extra-verbose  Be extra verbose"
  48.     echo
  49.     echo "Calls emerge, all other options are used for it (e. g. -p, --pretend)."
  50.     echo
  51.     echo "Report bugs to <http://bugs.gentoo.org>"
  52.     exit 0
  53. fi
  54.  
  55. echo "Configuring search environment for revdep-rebuild"
  56.  
  57. # Obey PORTAGE_NICENESS
  58. PORTAGE_NICENESS=$(portageq envvar PORTAGE_NICENESS)
  59. [ ! -z "$PORTAGE_NICENESS" ] && renice $PORTAGE_NICENESS $$ > /dev/null
  60.  
  61. # Update the incremental variables using /etc/profile.env, /etc/ld.so.conf,
  62. # portage, and the environment
  63.  
  64. # Read the incremental variables from environment and portage
  65. # Until such time as portage supports these variables as incrementals
  66. # The value will be what is in /etc/make.conf
  67. PRELIMINARY_SEARCH_DIRS="$SEARCH_DIRS $(portageq envvar SEARCH_DIRS)"
  68. PRELIMINARY_SEARCH_DIRS_MASK="$SEARCH_DIRS_MASK $(portageq envvar SEARCH_DIRS_MASK)"
  69. PRELIMINARY_LD_LIBRARY_MASK="$LD_LIBRARY_MASK $(portageq envvar LD_LIBRARY_MASK)"
  70.  
  71. # Add the defaults
  72. if [ -d /etc/revdep-rebuild ]
  73. then
  74.     for file in $(ls /etc/revdep-rebuild)
  75.     do
  76.         PRELIMINARY_SEARCH_DIRS="$PRELIMINARY_SEARCH_DIRS $(. /etc/revdep-rebuild/${file}; echo $SEARCH_DIRS)"
  77.         PRELIMINARY_SEARCH_DIRS_MASK="$PRELIMINARY_SEARCH_DIRS_MASK $(. /etc/revdep-rebuild/${file}; echo $SEARCH_DIRS_MASK)"
  78.         PRELIMINARY_LD_LIBRARY_MASK="$PRELIMINARY_LD_LIBRARY_MASK $(. /etc/revdep-rebuild/${file}; echo $LD_LIBRARY_MASK)"
  79.     done
  80. else
  81.     PRELIMINARY_SEARCH_DIRS="$PRELIMINARY_SEARCH_DIRS /bin /sbin /usr/bin /usr/sbin /lib* /usr/lib*"
  82.     PRELIMINARY_SEARCH_DIRS_MASK="$PRELIMINARY_SEARCH_DIRS_MASK /opt/OpenOffice /usr/lib/openoffice"
  83.     PRELIMINARY_LD_LIBRARY_MASK="$PRELIMINARY_LD_LIBRARY_MASK libodbcinst.so libodbc.so libjava.so libjvm.so"
  84. fi
  85.  
  86. # Get the ROOTPATH and PATH from /etc/profile.env
  87. if [ -e "/etc/profile.env" ]
  88. then
  89.     PRELIMINARY_SEARCH_DIRS="$PRELIMINARY_SEARCH_DIRS $((. /etc/profile.env; echo ${ROOTPATH}:${PATH}) | tr ':' ' ')"
  90. fi
  91.  
  92. # Get the directories from /etc/ld.so.conf
  93. if [ -e /etc/ld.so.conf ]
  94. then
  95.     PRELIMINARY_SEARCH_DIRS="$PRELIMINARY_SEARCH_DIRS $(grep -v "^#" /etc/ld.so.conf | tr '\n' ' ')"
  96. fi    
  97.  
  98. # Set the final variables
  99. # Note: Using $(echo $variable) removes extraneous spaces from variable assignment
  100. unset SEARCH_DIRS
  101. for i in $(echo $PRELIMINARY_SEARCH_DIRS)
  102. do
  103.     [ "$i" = "-*" ] && break
  104.     # Append a / at the end so that links and directories are treated the same by find
  105.     # Remove any existing trailing slashes to prevent double-slashes
  106.     SEARCH_DIRS="$(echo $SEARCH_DIRS ${i/%\//}/)"
  107. done
  108.  
  109. unset SEARCH_DIRS_MASK
  110. for i in $(echo $PRELIMINARY_SEARCH_DIRS_MASK)
  111. do
  112.     [ "$i" = "-*" ] && break
  113.     SEARCH_DIRS_MASK="$(echo $SEARCH_DIRS_MASK $i)"
  114. done
  115.  
  116. unset LD_LIBRARY_MASK
  117. for i in $(echo $PRELIMINARY_LD_LIBRARY_MASK)
  118. do
  119.     [ "$i" = "-*" ] && break
  120.     LD_LIBRARY_MASK="$(echo $LD_LIBRARY_MASK $i)"
  121. done
  122.  
  123. # Use the color preference from portage
  124. NOCOLOR=$(portageq envvar NOCOLOR)
  125.  
  126. # Base of temporary files names.
  127. LIST=~/.revdep-rebuild
  128.  
  129. shopt -s nullglob
  130. shopt -s expand_aliases
  131. unalias -a
  132.  
  133. # Color Definitions
  134. NO="\x1b[0m"
  135. BR="\x1b[0;01m"
  136. CY="\x1b[36;01m"
  137. GR="\x1b[32;01m"
  138. RD="\x1b[31;01m"
  139. YL="\x1b[33;01m"
  140. BL="\x1b[34;01m"
  141.  
  142. alias echo_v=echo
  143.  
  144. PACKAGE_NAMES=false
  145. SONAME="not found"
  146. SONAME_GREP=grep
  147. SEARCH_BROKEN=true
  148. EXTRA_VERBOSE=false
  149. KEEP_TEMP=false
  150.  
  151. EMERGE_OPTIONS=""
  152. PRELIMINARY_CALLED_OPTIONS=""
  153. while [ ! -z "$1" ] ; do
  154.     case "$1" in
  155.     -X | --package-names )
  156.         PACKAGE_NAMES=true
  157.         PRELIMINARY_CALLED_OPTIONS="${PRELIMINARY_CALLED_OPTIONS} --package_names"
  158.         shift
  159.         ;;
  160.     -q | --quiet )
  161.         alias echo_v=:
  162.         EMERGE_OPTIONS="${EMERGE_OPTIONS} $1"
  163.         shift
  164.         ;;
  165.     --library=* | --soname=* | --soname-regexp=* )
  166.         SONAME="${1#*=}"
  167.         SEARCH_BROKEN=false
  168.         PRELIMINARY_CALLED_OPTIONS="${PRELIMINARY_CALLED_OPTIONS} --library=${SONAME}"
  169.         shift
  170.         ;;
  171.     --library | --soname | --soname-regexp )
  172.         SONAME="$2"
  173.         SEARCH_BROKEN=false
  174.         PRELIMINARY_CALLED_OPTIONS="${PRELIMINARY_CALLED_OPTIONS} --library=${SONAME}"
  175.         shift 2
  176.         ;;
  177.     -nc | --no-color )
  178.         NOCOLOR=true
  179.         shift
  180.         ;;
  181.     -i | --ignore )
  182.         rm -f ${LIST}*
  183.         shift
  184.         ;;
  185.     --keep-temp )
  186.         KEEPTEMP=true
  187.         shift
  188.         ;;
  189.     -vv | --extra-verbose )
  190.         EXTRA_VERBOSE=true
  191.         shift
  192.         ;;
  193.     -- )
  194.         shift
  195.         ;;
  196.     * )
  197.         EMERGE_OPTIONS="${EMERGE_OPTIONS} $1"
  198.         shift
  199.         ;;
  200.     esac
  201. done
  202.  
  203. EMERGE_OPTIONS=$(echo $EMERGE_OPTIONS | sed 's/^ //')
  204.  
  205. if [ -z "$PRELIMINARY_CALLED_OPTIONS" ]
  206. then
  207.     CALLED_OPTIONS=""
  208. else
  209.     for i in $(echo $PRELIMINARY_CALLED_OPTIONS | tr ' ' '\n'| sort)
  210.     do
  211.         CALLED_OPTIONS="$(echo $CALLED_OPTIONS $i)"
  212.     done
  213. fi
  214.  
  215. if [ "$NOCOLOR" = "yes" -o "$NOCOLOR" = "true" ]
  216. then
  217.     NOCOLOR=true
  218. else
  219.     NOCOLOR=false
  220. fi
  221.  
  222. # Make the NOCOLOR variable visible to emerge
  223. export NOCOLOR
  224.  
  225. if $NOCOLOR
  226. then
  227.     NO=""
  228.     BR=""
  229.     CY=""
  230.     GR=""
  231.     RD=""
  232.     YL=""
  233.     BL=""
  234. fi
  235.  
  236. function set_trap () {
  237.     trap "rm_temp $1" SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
  238. }
  239.  
  240. function rm_temp () {
  241.     echo " terminated."
  242.     echo "Removing incomplete $1."
  243.     rm $1
  244.     echo
  245.     exit 1
  246. }
  247.  
  248. if $SEARCH_BROKEN ; then
  249.     SONAME_SEARCH="$SONAME"
  250.     LLIST=$LIST
  251.     HEAD_TEXT="broken by a package update"
  252.     OK_TEXT="Dynamic linking on your system is consistent"
  253.     WORKING_TEXT=" consistency"
  254. else
  255.     # first case is needed to test against /path/to/foo.so
  256.     if [ ${SONAME:0:1} == '/' ] ; then 
  257.         # Set to "<space>$SONAME<space>"
  258.         SONAME_SEARCH=" $SONAME "
  259.     else
  260.         # Set to "<tab>$SONAME<space>"
  261.         SONAME_SEARCH="    $SONAME "
  262.     fi
  263.     LLIST=${LIST}_$(echo "$SONAME_SEARCH$SONAME" | md5sum | head -c 8)
  264.     HEAD_TEXT="using $SONAME"
  265.     OK_TEXT="There are no dynamic links to $SONAME"
  266.     WORKING_TEXT=""
  267. fi
  268.  
  269. # If any of our temporary files are older than 1 day, remove them all
  270. [ "$(find "${LIST%/*}/." ! -name . -prune -name "${LIST##*/}*" -type f -mmin +1440)" != "" ] && rm -f ${LIST}*
  271.  
  272. # Don't use our previous files if environment doesn't match
  273. if [ -f $LIST.0_env ]
  274. then
  275.     PREVIOUS_SEARCH_DIRS=$(. ${LIST}.0_env; echo "$SEARCH_DIRS")
  276.     PREVIOUS_SEARCH_DIRS_MASK=$(. ${LIST}.0_env; echo "$SEARCH_DIRS_MASK")
  277.     PREVIOUS_LD_LIBRARY_MASK=$(. ${LIST}.0_env; echo "$LD_LIBRARY_MASK")
  278.     PREVIOUS_OPTIONS=$(. ${LIST}.0_env; echo "$CALLED_OPTIONS")
  279.     if [ "$PREVIOUS_SEARCH_DIRS" != "$SEARCH_DIRS" ] || \
  280.        [ "$PREVIOUS_SEARCH_DIRS_MASK" != "$SEARCH_DIRS_MASK" ] || \
  281.        [ "$PREVIOUS_LD_LIBRARY_MASK" != "$LD_LIBRARY_MASK" ] || \
  282.        [ "$PREVIOUS_OPTIONS" != "$CALLED_OPTIONS" ] 
  283.     then
  284.         echo
  285.         echo "Environment mismatch from previous run, deleting temporary files..."
  286.         rm -f ${LIST}*
  287.     fi
  288. fi
  289.  
  290. # Log our environment
  291. echo "SEARCH_DIRS=\"$SEARCH_DIRS\"" > $LIST.0_env
  292. echo "SEARCH_DIRS_MASK=\"$SEARCH_DIRS_MASK\"" >> $LIST.0_env
  293. echo "LD_LIBRARY_MASK=\"$LD_LIBRARY_MASK\"" >> $LIST.0_env
  294. echo "CALLED_OPTIONS=\"$CALLED_OPTIONS\"" >> $LIST.0_env
  295. echo "EMERGE_OPTIONS=\"$EMERGE_OPTIONS\"" >> $LIST.0_env
  296.  
  297. if $EXTRA_VERBOSE
  298. then
  299.     echo
  300.     echo "revdep-rebuild environment:"
  301.     cat $LIST.0_env
  302. fi
  303.  
  304. echo
  305. echo "Checking reverse dependencies..."
  306. echo
  307. echo "Packages containing binaries and libraries $HEAD_TEXT"
  308. echo "will be emerged."
  309.  
  310. echo
  311. echo -n -e "${GR}Collecting system binaries and libraries...${NO}"
  312.  
  313. if [ -f $LIST.1_files ]
  314. then
  315.     echo " using existing $LIST.1_files."
  316. else
  317.     # Be safe and remove any extraneous temporary files
  318.     rm -f ${LIST}.[1-9]_*
  319.  
  320.     set_trap "$LIST.1_*"
  321.  
  322.     # Hack for broken versions of find. I'm using a case statement in case I have to add more
  323.     find_version=$(find --version 2>/dev/null | awk '/find/ {print $NF}')
  324.     case "$find_version" in
  325.     4.2.25 | 4.2.27 )
  326.         find $SEARCH_DIRS -type f \( -perm /u+x -o -name '*.so' -o -name '*.so.*' \) 2>/dev/null | sort | uniq >$LIST.0_files
  327.         ;;
  328.     * )
  329.         find $SEARCH_DIRS -type f \( -perm +u+x -o -name '*.so' -o -name '*.so.*' \) 2>/dev/null | sort | uniq >$LIST.0_files
  330.         ;;
  331.     esac
  332.  
  333.     # Remove files that match SEARCH_DIR_MASK
  334.     for dir in $SEARCH_DIRS_MASK
  335.     do
  336.         grep -v "^$dir" $LIST.0_files > $LIST.1_files
  337.         mv $LIST.1_files $LIST.0_files
  338.     done
  339.     
  340.     mv $LIST.0_files $LIST.1_files
  341.     echo -e " done.\n  ($LIST.1_files)"
  342. fi
  343.  
  344. if $SEARCH_BROKEN ; then
  345.     echo
  346.     echo -n -e "${GR}Collecting complete LD_LIBRARY_PATH...${NO}"
  347.     if [ -f $LIST.2_ldpath ] ; then
  348.         echo " using existing $LIST.2_ldpath."
  349.     else
  350.         set_trap "$LIST.2_ldpath"
  351.         # Ensure that the "trusted" lib directories are at the start of the path
  352.         (
  353.             echo /lib* /usr/lib* | sed 's/ /:/g'
  354.             sed '/^#/d;s/#.*$//' </etc/ld.so.conf
  355.             sed 's:/[^/]*$::' <$LIST.1_files | sort -ru
  356.         ) | tr '\n' : | tr -d '\r' | sed 's/:$//' >$LIST.2_ldpath
  357.         echo -e " done.\n  ($LIST.2_ldpath)"
  358.     fi
  359.     export COMPLETE_LD_LIBRARY_PATH="$(cat $LIST.2_ldpath)"
  360. fi
  361.  
  362. echo
  363. echo -n -e "${GR}Checking dynamic linking$WORKING_TEXT...${NO}"
  364. if [ -f $LLIST.3_rebuild ] ; then
  365.     echo " using existing $LLIST.3_rebuild."
  366. else
  367.     echo_v
  368.     set_trap "$LLIST.3_rebuild"
  369.     LD_MASK="\\(    $(echo "$LD_LIBRARY_MASK" | sed 's/\./\\./g;s/ / \\|    /g') \\)"
  370.     echo -n >$LLIST.3_rebuild
  371.     cat $LIST.1_files | while read FILE ; do
  372.     # Note: double checking seems to be faster than single
  373.     # with complete path (special add ons are rare).
  374.     if ldd "$FILE" 2>/dev/null | grep -v "$LD_MASK" | $SONAME_GREP -q "$SONAME_SEARCH" ; then
  375.         if $SEARCH_BROKEN ; then
  376.             if LD_LIBRARY_PATH="$COMPLETE_LD_LIBRARY_PATH" ldd "$FILE" 2>/dev/null | grep -v "$LD_MASK" | $SONAME_GREP -q "$SONAME_SEARCH" ; then
  377.                 # FIX: I hate duplicating code
  378.                 # Only build missing direct dependencies
  379.                 ALL_MISSING_LIBS=$(ldd "$FILE" 2>/dev/null | sort -u | sed -n 's/    \(.*\) => not found/\1/p' | tr '\n' ' ' | sed 's/ $//' )
  380.                 REQUIRED_LIBS=$(objdump -x $FILE | grep NEEDED | awk '{print $2}' | tr '\n' ' ' | sed 's/ $//')
  381.                 MISSING_LIBS=""
  382.                 for lib in $ALL_MISSING_LIBS
  383.                 do
  384.                     if echo $REQUIRED_LIBS | grep -q $lib
  385.                     then
  386.                         MISSING_LIBS="$MISSING_LIBS $lib"
  387.                     fi
  388.                 done
  389.                 if [ "$MISSING_LIBS" != "" ]
  390.                 then
  391.                     echo "$FILE" >>$LLIST.3_rebuild
  392.                     echo_v "  broken $FILE (requires ${MISSING_LIBS})"
  393.                 fi
  394.             fi
  395.         else
  396.             # FIX: I hate duplicating code
  397.             # Only rebuild for direct dependencies
  398.             ALL_MISSING_LIBS=$(ldd "$FILE" 2>/dev/null | sort -u | $SONAME_GREP "$SONAME_SEARCH" | awk '{print $1}' | tr '\n' ' ' | sed 's/ $//' )
  399.             REQUIRED_LIBS=$(objdump -x $FILE | grep NEEDED | awk '{print $2}' | tr '\n' ' ' | sed 's/ $//')
  400.             MISSING_LIBS=""
  401.             for lib in $ALL_MISSING_LIBS
  402.             do
  403.                 if echo $REQUIRED_LIBS | grep -q $lib
  404.                 then
  405.                     MISSING_LIBS="$MISSING_LIBS $lib"
  406.                 fi
  407.             done
  408.             if [ "$MISSING_LIBS" != "" ]
  409.             then
  410.                 echo "$FILE" >>$LLIST.3_rebuild
  411.                 echo_v "  found $FILE"
  412.             fi
  413.         fi
  414.     fi
  415.     done
  416.     echo -e " done.\n  ($LLIST.3_rebuild)"
  417. fi
  418.  
  419. if $PACKAGE_NAMES ; then
  420.     EXACT_EBUILDS=false
  421.  
  422.     echo
  423.     echo -n -e "${GR}Assigning files to packages...${NO}"
  424.     if [ -f $LLIST.4_packages_raw ] ; then
  425.         echo " using existing $LLIST.4_packages_raw."
  426.     else
  427.         set_trap "$LLIST.4_packages*"
  428.         echo -n >$LLIST.4_packages_raw
  429.         echo -n >$LLIST.4_package_owners
  430.         cat $LLIST.3_rebuild | while read FILE ; do
  431.             EXACT_PKG="$(echo $FILE | sed 's/^/obj /' | (cd /var/db/pkg; grep -l -f - */*/CONTENTS) | sed s:/CONTENTS:: )"
  432.             # Ugly sed hack to strip version information
  433.             PKG="$(echo $EXACT_PKG | sed 's/-r[0-9].*$//;s/\(^.*\/*\)-.*$/\1/')"
  434.             if [ -z "$PKG" ] ; then
  435.                 echo -n -e "\n  ${RD}*** $FILE not owned by any package is broken! ***${NO}"
  436.                 echo "$FILE -> (none)" >> $LLIST.4_package_owners
  437.                 echo_v -n -e "\n  $FILE -> (none)"
  438.             else
  439.                 echo "$EXACT_PKG" >> $LLIST.4_packages_raw
  440.                 echo "$FILE -> $EXACT_PKG" >> $LLIST.4_package_owners
  441.                 echo_v -n -e "\n  $FILE -> $PKG"
  442.             fi
  443.         done
  444.         echo_v
  445.         echo -e " done.\n  ($LLIST.4_packages_raw, $LLIST.4_package_owners)"
  446.     fi
  447.  
  448.     echo
  449.     echo -n -e "${GR}Cleaning list of packages to rebuild...${NO}"
  450.     if [ -f $LLIST.4_packages ] ; then
  451.         echo " using existing $LLIST.4_packages."
  452.     else
  453.         sort -u $LLIST.4_packages_raw >$LLIST.4_packages
  454.         echo -e " done.\n  ($LLIST.4_packages)"
  455.     fi
  456.  
  457.     echo
  458.     echo -n -e "${GR}Assigning packages to ebuilds...${NO}"
  459.     if [ -f $LLIST.4_ebuilds ] ; then
  460.         echo " using existing $LLIST.4_ebuilds."
  461.     else
  462.         if [ -s "$LLIST.4_packages" ]
  463.         then
  464.             set_trap "$LLIST.4_ebuilds"
  465.             cat $LLIST.4_packages | while read EXACT_PKG
  466.             do
  467.                 # Get the slot
  468.                 PKG="$(echo $EXACT_PKG | sed 's/-r[0-9].*$//;s/\(^.*\/*\)-.*$/\1/')"
  469.                 SLOT=$(cat /var/db/pkg/${EXACT_PKG}/SLOT)
  470.                 # If SLOT is equal to 0, then just see what portage says is latest version
  471.                 if [ "$SLOT" = "0" ]
  472.                 then
  473.                     emerge --nospinner --pretend --nodeps $PKG | sed -n 's/ //g;s/\[[^]]*\]//gp'
  474.                     continue
  475.                 fi
  476.                 # Otherwise mask the other SLOTTED versions and check for latest
  477.                 OTHER_VERSIONS=$(/usr/lib/gentoolkit/bin/find_pkgs.py $PKG | grep -v "($SLOT)" | awk '{print $2}')
  478.                 if [ -f /etc/portage/package.mask ]
  479.                 then
  480.                     mv -f /etc/portage/package.mask /etc/portage/package.mask.revdep-rebuild.backup
  481.                 else
  482.                     # Make sure that /etc/portage/package.mask exists
  483.                     mkdir -p /etc/portage
  484.                     touch /etc/portage/package.mask
  485.                 fi
  486.                 for pkg_version in $(echo $OTHER_VERSIONS | tr '\n' ' ') 
  487.                 do
  488.                     echo "=${PKG}-${pkg_version}" >> /etc/portage/package.mask
  489.                 done
  490.                 emerge --nospinner --pretend --nodeps $PKG | sed -n 's/ //g;s/\[[^]]*\]//gp'
  491.                 if [ -f /etc/portage/package.mask.revdep-rebuild.backup ]
  492.                 then
  493.                     mv -f /etc/portage/package.mask.revdep-rebuild.backup /etc/portage/package.mask
  494.                 else
  495.                     rm -f /etc/portage/package.mask
  496.                 fi
  497.             done > $LLIST.4_ebuilds
  498.             echo -e " done.\n  ($LLIST.4_ebuilds)"
  499.         else
  500.             echo " Nothing to rebuild"
  501.             echo -n > $LLIST.4_ebuilds
  502.         fi
  503.     fi
  504. else
  505.     EXACT_EBUILDS=true
  506.  
  507.     echo
  508.     echo -n -e "${GR}Assigning files to ebuilds...${NO}"
  509.     if [ -f $LLIST.4_ebuilds ] ; then
  510.         echo " using existing $LLIST.4_ebuilds."
  511.     else
  512.         if [ -s "$LLIST.3_rebuild" ] ; then
  513.             set_trap "$LLIST.4_ebuilds"
  514.             cat $LLIST.3_rebuild | sed 's/^/obj /;s/$/ /' |
  515.             (
  516.                 cd /var/db/pkg
  517.                 fgrep -l -f - */*/CONTENTS
  518.             ) | sed s:/CONTENTS:: > $LLIST.4_ebuilds
  519.             echo -e " done.\n  ($LLIST.4_ebuilds)"
  520.         else
  521.             echo " Nothing to rebuild"
  522.             echo -n > $LLIST.4_ebuilds
  523.         fi
  524.     fi
  525.  
  526. fi
  527.  
  528. echo
  529. echo -n -e "${GR}Evaluating package order...${NO}"
  530. if [ -f $LLIST.5_order ] ; then
  531.     echo " using existing $LLIST.5_order."
  532. else
  533.     RAW_REBUILD_LIST="$(cat $LLIST.4_ebuilds | sed s/^/=/ | tr '\n' ' ')"
  534.     if [ ! -z "$RAW_REBUILD_LIST" ] ; then
  535.         REBUILD_GREP="^\\($( (emerge --nospinner --pretend --oneshot --nodeps $RAW_REBUILD_LIST ; echo $? >$LLIST.5_status ) | sed -n 's/\./\\&/g;s/ //g;s/$/\\/;s/\[[^]]*\]//gp' | tr '\n' '|' | sed 's/|$//'))\$"
  536.         if [ $(cat $LLIST.5_status) -gt 0 ] ; then
  537.             echo ""
  538.             echo -e "${RD}Warning: Failed to resolve package order."
  539.             echo -e "Will merge in \"random\" order!${NO}"
  540.             echo "Possible reasons:"
  541.             echo "- An ebuild is no longer in the portage tree."
  542.             echo "- An ebuild is masked, use /etc/portage/packages.keyword"
  543.             echo "  and/or /etc/portage/package.unmask to unmask it"
  544.             for i in . . . . . ; do
  545.                 echo -n -e '\a.'
  546.                 sleep 1
  547.             done
  548.             ln -f $LLIST.4_ebuilds $LLIST.5_order
  549.         else
  550.             emerge --nospinner --pretend --oneshot --emptytree $RAW_REBUILD_LIST | sed -n 's/ //g;s/^.*\]//p' | grep "$REBUILD_GREP" >$LLIST.5_order
  551.         fi
  552.     else
  553.         echo -n "" >$LLIST.5_order
  554.     fi
  555.     echo -e " done.\n  ($LLIST.5_order)"
  556. fi
  557.  
  558. REBUILD_LIST="$(cat $LLIST.5_order | sed s/^/=/ | tr '\n' ' ')"
  559.  
  560. trap - SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
  561.  
  562. if [ -z "$REBUILD_LIST" ] ; then
  563.     echo -e "\n${GR}$OK_TEXT... All done.${NO} "
  564.     if [ ! $KEEPTEMP ]
  565.     then
  566.         rm $LIST.[0-2]_*
  567.         rm $LLIST.[3-9]_*
  568.     fi
  569.     exit 0
  570. fi
  571.  
  572. IS_REAL_MERGE=true
  573. echo " $EMERGE_OPTIONS " | grep -q '\( -p \| --pretend \| -f \| --fetchonly \)' && IS_REAL_MERGE=false
  574.  
  575. echo
  576. echo -e "${GR}All prepared. Starting rebuild...${NO}"
  577.  
  578. echo "emerge --oneshot $EMERGE_OPTIONS $REBUILD_LIST"
  579.  
  580. if $IS_REAL_MERGE ; then
  581.     for i in . . . . . . . . . . ; do
  582.         echo -n -e '\a.'
  583.         sleep 1
  584.     done
  585.     echo
  586. fi
  587.  
  588. #if $EXACT_EBUILDS ; then
  589. # Uncomment following, if you want to recompile masked ebuilds.
  590. ## FIXME: Check for PORTDIR_OVERLAY
  591. #    echo -e "${GR}Temporarilly disabling package mask...${NO}"
  592. #    trap "mv -i /usr/portage/profiles/package.mask.hidden /usr/portage/profiles/package.mask ; echo -e "\\n\\nTerminated." ; exit 1" \
  593. #    SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
  594. #    mv -i /usr/portage/profiles/package.mask /usr/portage/profiles/package.mask.hidden
  595. #fi
  596.  
  597. # Run in background to correctly handle Ctrl-C
  598. (
  599.     emerge --oneshot $EMERGE_OPTIONS $REBUILD_LIST
  600.     echo $? >$LLIST.6_status
  601. ) &
  602. wait
  603.  
  604. #if $EXACT_EBUILDS ; then
  605. #    mv -i /usr/portage/profiles/package.mask.hidden /usr/portage/profiles/package.mask
  606. #    trap - SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
  607. #fi
  608.  
  609. if [ "$(cat $LLIST.6_status)" -gt 0 ] ; then
  610.     echo
  611.     echo -e "${RD}revdep-rebuild failed to emerge all packages${NO}"
  612.     echo -e "${RD}you have the following choices:${NO}"
  613.     echo
  614.     echo "- if emerge failed during the build, fix the problems and re-run revdep-rebuild"
  615.     echo "    or"
  616.     echo "- use -X or --package-names as first argument (trys to rebuild package, not exact"
  617.     echo "  ebuild)"
  618.     echo "    or"
  619.     echo "- set ACCEPT_KEYWORDS=\"~<your platform>\" and/or /etc/portage/package.unmask"
  620.     echo "  (and remove $LLIST.5_order to be evaluated again)"
  621.     echo "    or"
  622.     echo "- modify the above emerge command and run it manually"
  623.     echo "    or"
  624.     echo "- compile or unmerge unsatisfied packages manually, remove temporary files and"
  625.     echo "  try again (you can edit package/ebuild list first)"
  626.     echo
  627.     echo -e "${GR}To remove temporary files, please run:${NO}"
  628.     echo "rm $LIST*.?_*"
  629.     exit $(cat $LLIST.6_status)
  630. else
  631.     if $IS_REAL_MERGE ; then
  632.         trap "echo -e \" terminated. Please remove them manually:\nrm $LIST*.?_*\" ; exit 1" \
  633.             SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
  634.         echo -n -e "${GR}Build finished correctly. Removing temporary files...${NO} "
  635.         echo
  636.         rm $LIST.[0-2]_*
  637.         rm $LLIST.[3-9]_*
  638.         echo "You can re-run revdep-rebuild to verify that all libraries and binaries"
  639.         echo "are fixed. If some inconsistency remains, it can be orphaned file, deep"
  640.         echo "dependency, binary package or specially evaluated library."
  641.     else
  642.         echo -e "${GR}Now you can remove -p (or --pretend) from arguments and re-run revdep-rebuild.${NO}"
  643.     fi
  644. fi
  645. exit 0
  646.